#ifndef FriendStation_H
#define FriendStation_H
#include "boolean.h"

//#include "kata.h"
/*	kata.h adalah char*.h yang dibuat sendiri (hayoloh Mirza! :p) 
	Eh, dikoreksi dong .h ini! :D	*/

/* ADT Social Network Graph yang direpresentasikan sebagai List to User Address (Edge List) */

#define nil NULL

typedef struct {
	char* Email, Nama, TglLahir, KotaAsal, Universitas, SMU;
} InfoUser;

typedef struct {
	Uaddress UFirst;
} MemberList;
typedef tMemberList *Uaddress;
typedef struct tMemberList {
	InfoUser Info;
	Uaddress Next;
	FriendList Friends;
} MemberList;

//User's Friends
typedef struct {
	Faddress FFirst;
} FriendList;
typedef tFriendList *Faddress;
typedef struct tFriendList {
	InfoUser Info;
	Faddress NextFriends;
} FriendList;


//Selektor
#define FirstUser(L) ((L).UFirst)
#define FirstFriend(L) ((L).FFirst)
#define NextUser(P) (P)->Next
#define NextFriend(P) (P)->NextFriends
#define InfoEmail(P) ((P)->Info).Email
#define InfoNama(P) ((P)->Info).Nama
#define InfoTglLahir(P) ((P)->Info).TglLahir
#define InfoKotaAsal(P) ((P)->Info).KotaAsal
#define InfoUniv(P) ((P)->Info).Universitas
#define InfoSMU(P) ((P)->Info).SMU

/*
	MODUS : ADMINISTRASI / PENGGUNA
	Perintah untuk modus Administrasi : 
		>load
		>adduser
		>modifyuser
		>deluser
		>list
		>reload
		>save
		>exit
	Perintah untuk modus Pengguna :
		>>birthday
		>>same
		>>notfriendyet
		>>friend
		>>unfriend
		>>updatedata
*/

/**** Modus Administrator ****/
void ReadCommand (char* *cmd);
/*	I.S perintah (sembarang) terdefinisi dan diakhiri oleh #
	F.S perintah dibaca dan dimasukkan ke variabel perintah */
	
void CreateMemberList (MemberList *L);
/*	I.S. sembarang
	F.S. Terbentuk list L kosong */

void CreateFriendList (FriendList *F);
/*	I.S. sembarang
	F.S terbentuk list F kosong */

void Load (char* FileInput, MemberList *L); 
/*	I.S sembarang, list L sudah terbentuk 
	F.S file input diloading ke dalam struktur-struktur internal yang dibutuhkan oleh sistem (membentuk struktur graf berarah dari para pengguna sesuai dengan isi 	    file input */

boolean ChangeUser (char* UserID); 
/*	I.S operator berada pada Modus Administrasi
	F.S operator/pengguna masuk ke Modus Pengguna. Modus Pengguna ditandai dengan prompt baru dengan format <user-id> >> 
	Mengembalikan nilai true jika sudah ganti ke Modus Pengguna */
   
void PrintPengguna (char* CurrentUser);
/*	I.S operator berada pada Modus Pengguna
	Menuliskan prompt <user-id> >> */

void Save (char* FileInput, MemberList *L); 
/*	I.S sembarang
	F.S Kondisi terakhir dari jejaring sosial dituliskan pada file tersebut.
	Jika file adalah file baru, maka harus di-create terlebih dahulu
	Jika file berbeda dari file yang digunakan pada saat load, makan file input load tetap
	Jika argumen Save tidak diberikan, maka secara default, kondisi terakhir pada file input yang digunakan pada saat load terakhir */

void Reload (char* FileInput, MemberList *L);
/*	I.S sembarang
	F.S melakukan load ulang / mengembalikan ke kondisi semula sesuai dengan kondisi pada file input */
	
void AddUser (MemberList *U, InfoUser ID);
/* 	I.S email USER belum terdefinisi di U. U mungkin kosong.
	F.S Insert USER sebagai elemen terakhir dari U dengan urut membesar berdasarkan Nama 
	AddUser menggunakan procedure InsSort (menyisipkan user baru dengan terurut membesar berdasarkan nama)	
*/
	
void ModifyUser (MemberList *U, char* E); 
/*	I.S P terdefinisi di U
	F.S Data pribadi dari user yang beralamat email E diubah. 
	Data pribadi yang diubah antara lain : nama, tanggal lahir, kota asal, universitas, dan SMU
	EMAIL TIDAK DIUBAH 
	Bila nama diubah, urutan user di MemberList diurutkan lagi berdasarkan nama	
*/
	
void DelUser (MemberList *U, char* E);
/*	I.S P terdefinisi di U
	F.S Data pribadi (nama, tanggal lahir, kota asal, universitas, SMU) dari pengguna yang beralamat-email E dihapus.
	Perintah ini harus menjamin integrity dari seluruh data (seperti friend relations) */
	
void  List (MemberList *U, char* Field, char* state);
/*	I.S U tidak kosong
	F.S isi U ditampilkan sesuai state (asc/desc) berdasarkan Field tertentu (email/nama/tgl lahir/kota asal/universitas/SMU) 
	Secara default, List akan ditampilakn daftar semua pengguna terurut asc berdasarkan Nama.
	Keterangan : asc : menampilkan data dalam keadaan terurut membesar
			   desc: menampilkan data dalam keadaan terurut mengecil */

void Exit;
/*	I.S sembarang
	F.S keluar dari program simulasi jejaring sosial */
	
	
/**** Modus Pengguna ****/

void Friend (FriendList *F, char* UserId);
/*	I.S UserId bisa kosong, atau berisi email orang lain
	F.S Jika UserId kosong : tampilkan semua 1st friend dari CurrentUser
	    Jika UserId berisi alamat email orang lain, pengguna dengan UserId tersebut ditambahkan sebagai 1st friend dari CurrentUser
*/

void UnFriend (FriendList *F, char* UserId);
/*	I.S UserId tidak kosong dan merupakan 1st friend dari CurrentUser
	F.S Hubungan pertemanan antara CurrentUser dan UserId dihapus
*/

void UpdateData (MemberList *L, char* CurrentUser);
/*	I.S	CurrentUser terdefinisi di dalam list L
		Operator berada dalam modus pengguna
	F.S	InfoUser dari CurrentUser diubah (email tidak boleh diubah). 
		Daftar user di list L terurut berdasarkan nama
*/

void ModifyUser (MemberList *L, char* UserID);
/*	I.S	UserID terdefinisi di dalam list L.
		Operator berada dalam modus administrasi
	F.S	InfoUser dari UserID diubah (email tidak boleh diubah).
		Daftar user di list L terurut berdasarkan nama	
*/

void Birthday (MemberList *L, char* CurrentUser, int day, int today); 
/*	I.S	CurrentUser dan day terdefinisi
	F.S	menampilakn list dari 1st friend dari CurrentUser yang berulang tahun dalam jangka waktu Day yang didefinisikan 	
		Bila hubungan pertemanan bukan 2 arah, tanggal lahir dari 1st friend tersebut harus di-masking 
*/

void Same (MemberList *L, char* CurrentUser, char* state);
/*	I.S
	F.S menampilkan list dari 1st, 2nd, 3rd friend yang memiliki sekolah (Universitas/SMU) atau kota asal yang sama dengan current user */

void notfriendyet (MemberList *L, char* CurrentUser);
/*	I.S sembarang
	F.S menampilkan list dari 2nd friend dan 3rd friend yang belum menjadi 1st friend dari current user */

void close;
/*	I.S berada pada Modus Pengguna
	F.S kembali ke Modus Administrasi */
	
/*** Fungsi Antara ***/
boolean IsFound (MemberList *L, char* field, char* S);
/*	I.S	S, field, dan L terdefinisi
	Field adalah Email/Nama/TglLahir/KotaAsal/Universitas/SMU
	F.S	mengembalikan true jika S ditemukan pada L
	(note : bila field adalah Nama, S berisi Joko, Ina, dll [misal])
*/

void FirstFriend (MemberList *L, char* CurrentUser, FriendList *F1);
// I.S CurrentUser terdefinisi di dalam L
// F.S 1st friend dari CurrentUser dimasukkan ke variabel F1
 
void SecondFriend (MemberList *L, char* CurrentUser, FriendList *F2);
// I.S CurrentUser terdefinisi di dalam L
// F.S 2nd friend dari CurrentUser dimasukkan ke variabel F2
// 2nd friend adalah teman dari 1st friend yang belum menjadi teman CurrentUser
 
void ThirdFriend (MemberList *L, char* CurrentUser, FriendList *F3);
// I.S CurrentUser terdefinisi di dalam L
// F.S 3rd friend dari CurrentUser dimasukkan ke variabel F3
// 3rd friend adalah teman dari 2nd friend yang belum menjadi teman CurrentUser

address CariAddress (MemberList L, char* CurrentUser);
//	I.S CurrentUser terdefinisi. L tidak kosong
//	F.S menghasilkan address dari CurrentUser (CurrentUser berisi email dari current user)

int HariKeN(MemberList *L,char* InfoBday);
// mengembalikan angka yang berupa hari ke berapa tanggal tersebut dalam tahun itu

#endif

